#define _HART_HANDLER_C_
/* Includes ---------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "hart_handler.h"
/* USER CODE END Includes */

/* Types ------------------------------------------------------------*/
/* USER CODE BEGIN Types */
typedef struct
{
	uint8_t ucAryPreamble[5];
	uint8_t ucStart;
	uint8_t ucbitPollingAddr : 4;
	uint8_t reserved : 2;
	uint8_t ucbitBurstMode : 1;
	uint8_t ucbitMasterAddr : 1;
	uint8_t ucCom;
	uint8_t ucSize;
	uint8_t ucParity;
	uint8_t *pucData;
}STHartShortAddrFrame;

typedef struct
{
	uint8_t ucAryPreamble[5];
	uint8_t ucStart;
	uint8_t ucbitMasterAddr : 1;
	uint8_t ucbitBurstMode : 1;
	uint8_t ucbitManufacturerID : 6;
	uint8_t ucDeviceType;
	uint32_t ulDeviceId;
	uint8_t ucCom;
	uint8_t ucSize;
	uint8_t ucParity;
	uint8_t *pucData;
}STHartLongAddrFrame;
/* USER CODE END Types */

/* Constants --------------------------------------------------------*/
/* USER CODE BEGIN Constants */

/* USER CODE END Constants */

/* Macro ------------------------------------------------------------*/
/* USER CODE BEGIN Macro */
#define HART_ADDR_HOST_SLAVE_SHORT                                   (0x02) // host slave short
#define HART_ADDR_HOST_SLAVE_LONG                                    (0x82) // host slave long
#define HART_ADDR_SLAVE_HOST_SHORT                                   (0x06) // slave host short
#define HART_ADDR_SLAVE_HOST_LONG                                    (0x86) // slave host long

// CRC
#define HART_MS_SHORT_CRC_CAL_LEN                                    (4)

// Command
#define UNIVERSAL_COMMAND0                                           (0)
#define UNIVERSAL_COMMAND1                                           (1)
#define UNIVERSAL_COMMAND2                                           (2)
#define UNIVERSAL_COMMAND3                                           (3)
#define UNIVERSAL_COMMAND6                                           (6)
/* USER CODE END Macro */

/* Variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
STHartRxData stHartRxData;
STHartShortAddrFrame stHartShortAddrFrame;
STHartLongAddrFrame stHartLongAddrFrame;

uint8_t gucFrameStartPos = 0;
/* USER CODE END Variables */

/* Function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FP */
void vHartRxBufferClr(void);
void vHartTxData(uint8_t *pdata, uint8_t ucSize);
void vUpdateRxFrameBuffer(uint8_t ucStart);
void vSlave2MasterResponse(uint8_t ucCmd);
EnumHartCmdId GetCmdID(uint8_t ucCom);
void vSysCmdMsgHander(void);
/* USER CODE END FP */

void vHartHandler(void)
{
	if(GET_UART0_HART_RX_FINISHED_FLG())
	{	
		gucFrameStartPos = 0;
		
		if((stHartRxData.ucAryBuffer[0] == 0xff) && (stHartRxData.ucAryBuffer[1] == 0xff))
		{
			if(stHartRxData.ucAryBuffer[2] != 0xff)
			{
				gucFrameStartPos = 2;
			}
			else if(stHartRxData.ucAryBuffer[3] != 0xff)
			{
				gucFrameStartPos = 3;
			}
			else if(stHartRxData.ucAryBuffer[4] != 0xff)
			{
				gucFrameStartPos = 4;
			}
			else if(stHartRxData.ucAryBuffer[5] != 0xff)
			{
				gucFrameStartPos = 5;
			}
			else if(stHartRxData.ucAryBuffer[6] != 0xff)
			{
				gucFrameStartPos = 6;
			}
			else if(stHartRxData.ucAryBuffer[7] != 0xff)
			{
				gucFrameStartPos = 7;
			}	
			else if(stHartRxData.ucAryBuffer[8] != 0xff)
			{
				gucFrameStartPos = 8;
			}
			else
			{
				// do nothing
			}
		}
		
		if(gucFrameStartPos != 0)
		{
			// System CMD Setup
			if((stHartRxData.ucAryBuffer[gucFrameStartPos] == 0xAA) && (stHartRxData.ucAryBuffer[gucFrameStartPos + 1] == 0x55))
			{
				vSysCmdMsgHander();
				
				return;
			}
			
			uint8_t ucCRC = 0;
			bool bRes = false;
			uint8_t ucCalCRCDataSize = 0;
			uint8_t ucCmd = 0;
			
			if(stHartRxData.ucAryBuffer[gucFrameStartPos] == HART_ADDR_HOST_SLAVE_SHORT)
			{
				uint8_t address = stHartRxData.ucAryBuffer[gucFrameStartPos + 1] & 0x0F;
				
				if(address != stLoopConfig.ucPollingAddr)
				{
					vHartRxBufferClr();
					CLR_UART0_HART_RX_FINISHED_FLG();
					
					return;
				}
				
				ucCalCRCDataSize = 4;
				
				ucCRC = ucGetCRC((uint8_t *)&stHartRxData.ucAryBuffer[gucFrameStartPos], ucCalCRCDataSize);
				
				if(ucCRC == stHartRxData.ucAryBuffer[gucFrameStartPos + 4])
				{
					vUpdateRxFrameBuffer(HART_ADDR_HOST_SLAVE_SHORT);
					bRes = true;
					ucCmd = stHartShortAddrFrame.ucCom;
				}
			}
			else if(stHartRxData.ucAryBuffer[gucFrameStartPos] == HART_ADDR_HOST_SLAVE_LONG)
			{
				uint32_t ulDeviceId = (stHartRxData.ucAryBuffer[gucFrameStartPos + 3] << 16) | (stHartRxData.ucAryBuffer[gucFrameStartPos + 4] << 8) | stHartRxData.ucAryBuffer[gucFrameStartPos + 5];
				
				if(ulDeviceId != stReadUniqueIdRes.ulDeviceId)
				{
					vHartRxBufferClr();
					CLR_UART0_HART_RX_FINISHED_FLG();
					
					return;
				}
				
				ucCalCRCDataSize = 7 + 1 + stHartRxData.ucAryBuffer[gucFrameStartPos + 7];
				
				ucCRC = ucGetCRC((uint8_t *)&stHartRxData.ucAryBuffer[gucFrameStartPos], ucCalCRCDataSize);
				
				if(ucCRC == stHartRxData.ucAryBuffer[gucFrameStartPos + ucCalCRCDataSize])
				{
					vUpdateRxFrameBuffer(HART_ADDR_HOST_SLAVE_LONG);
					bRes = true;
					ucCmd = stHartLongAddrFrame.ucCom;
				}
			}
			
			if(bRes == true)
			{
				vSlave2MasterResponse(ucCmd);
			}
		}
			
		vHartRxBufferClr();
		CLR_UART0_HART_RX_FINISHED_FLG();
	}
}

void vSysCmdMsgHander(void)
{
	uint8_t ucAryDataBuf[15] = {0xff, 0xff, 0xff, 0xff, 0xAA, 0x55, 0x01, 0x00, 0x0D, 0x0A, 0xff};
				
	vSystemSetup();
	
	while(GET_HART_CARRIER_DET());

	HART_RTS_L();
	vHartTxData(ucAryDataBuf, 15); // send one more byte
	HART_RTS_H();
	
	vHartRxBufferClr();
	CLR_UART0_HART_RX_FINISHED_FLG();
}

void vSlave2MasterResponse(uint8_t ucCmd)
{
	uint8_t ucAryDataBuf[48] = {0x00};
	uint8_t ucSize = 0;
	uint8_t const *pTemp = NULL;
	
	ucAryDataBuf[0] = 0xff;
	ucAryDataBuf[1] = 0xff;
	ucAryDataBuf[2] = 0xff;
	ucAryDataBuf[3] = 0xff;
	ucAryDataBuf[4] = 0xff;
	
	switch(GetCmdID(ucCmd))
	{
		case eHART_CMD0:
			ucSize = 34; // 5 + 4 + 24 + 1
			
			ucAryDataBuf[5] = HART_ADDR_SLAVE_HOST_SHORT;
			ucAryDataBuf[6] = (stHartShortAddrFrame.ucbitMasterAddr << 7) + (stHartShortAddrFrame.ucbitBurstMode << 6) + stHartShortAddrFrame.ucbitPollingAddr;
			ucAryDataBuf[7] = stHartShortAddrFrame.ucCom;
			ucAryDataBuf[8] = 24;
			ucAryDataBuf[9] = 0x00;
			ucAryDataBuf[10] = eCMD0_RES_CODE_SUCCESS;// response code
		
			ucAryDataBuf[11] = stReadUniqueIdRes.ucCmdByte0;
			ucAryDataBuf[12] = stReadUniqueIdRes.uiExpandDevType;
			ucAryDataBuf[13] = stReadUniqueIdRes.uiExpandDevType >> 8;
			ucAryDataBuf[14] = stReadUniqueIdRes.ucMiniNumOfPream;
			ucAryDataBuf[15] = stReadUniqueIdRes.ucHartMajorRev;
			ucAryDataBuf[16] = stReadUniqueIdRes.ucDevRevLevel;
			ucAryDataBuf[17] = stReadUniqueIdRes.ucSoftwareRev;
			ucAryDataBuf[18] = stReadUniqueIdRes.ucHardwareRevAndPhySigCode;
			ucAryDataBuf[19] = stReadUniqueIdRes.ucBitsFlags;
			ucAryDataBuf[20] = stReadUniqueIdRes.ulDeviceId >> 16;
			ucAryDataBuf[21] = stReadUniqueIdRes.ulDeviceId >> 8;
			ucAryDataBuf[22] = stReadUniqueIdRes.ulDeviceId;
			ucAryDataBuf[23] = stReadUniqueIdRes.ucMiniPreamRespMsg;
			ucAryDataBuf[24] = stReadUniqueIdRes.ucMaxDevVars;
			ucAryDataBuf[25] = stReadUniqueIdRes.uiConfigChgCnt;
			ucAryDataBuf[26] = stReadUniqueIdRes.uiConfigChgCnt >> 8;
			ucAryDataBuf[27] = stReadUniqueIdRes.ucBitsExtFieldDevStatus;
			ucAryDataBuf[28] = stReadUniqueIdRes.uiManufacturerIdCode >> 8;
			ucAryDataBuf[29] = stReadUniqueIdRes.uiManufacturerIdCode;
			ucAryDataBuf[30] = stReadUniqueIdRes.uiPrivateLabDisCode;
			ucAryDataBuf[31] = stReadUniqueIdRes.uiPrivateLabDisCode >> 8;
			ucAryDataBuf[32] = stReadUniqueIdRes.ucDevProfile;
		
			ucAryDataBuf[33] = ucGetCRC((uint8_t *)&ucAryDataBuf[5], 28); // 24 + 4
			break;
		
		case eHART_CMD1:
			ucSize = 21; // 5 + 8 + 0x07 + 1
		
			ucAryDataBuf[5] = HART_ADDR_SLAVE_HOST_LONG;
			ucAryDataBuf[6] = (stHartLongAddrFrame.ucbitMasterAddr << 7) + (stHartLongAddrFrame.ucbitBurstMode << 6) + stHartLongAddrFrame.ucbitManufacturerID;
			ucAryDataBuf[7] = 0x82;
			ucAryDataBuf[8] = 0x74;
			ucAryDataBuf[9] = 0x2E;
			ucAryDataBuf[10] = 0x96;
			ucAryDataBuf[11] = stHartLongAddrFrame.ucCom;
			ucAryDataBuf[12] = 0x07;
			ucAryDataBuf[13] = 0x00;
			ucAryDataBuf[14] = eCMD1_WARNING_UPDATE_FAILURE;
			//vExeCommands(eHART_CMD1, 0, ucAryDataBuf + 15);
		
			pTemp = (uint8_t *)&gfPVValue;
	
			gfPVValue = 1.6f;
			
			ucAryDataBuf[15] = stVariablesUnit.ePVUnit;
			ucAryDataBuf[16] = *(pTemp + 0);
			ucAryDataBuf[17] = *(pTemp + 1);
			ucAryDataBuf[18] = *(pTemp + 2);
			ucAryDataBuf[19] = *(pTemp + 3);
		
			ucAryDataBuf[20] = ucGetCRC((uint8_t *)&ucAryDataBuf[5], 15); // 0x07 + 8
			break;
		
		case eHART_CMD2:
			ucSize = 24; // 5 + 8 + 0x0A + 1
			
			ucAryDataBuf[5] = HART_ADDR_SLAVE_HOST_LONG;
			ucAryDataBuf[6] = (stHartLongAddrFrame.ucbitMasterAddr << 7) + (stHartLongAddrFrame.ucbitBurstMode << 6) + stHartLongAddrFrame.ucbitManufacturerID;
			ucAryDataBuf[7] = 0x82;
			ucAryDataBuf[8] = 0x74;
			ucAryDataBuf[9] = 0x2E;
			ucAryDataBuf[10] = 0x96;
			ucAryDataBuf[11] = stHartLongAddrFrame.ucCom;
			ucAryDataBuf[12] = 0x0A;
			ucAryDataBuf[13] = 0x00;
			ucAryDataBuf[14] = eCMD2_SUCCESS;
			vExeCommands(eHART_CMD2, 0, ucAryDataBuf + 15);
			
			ucAryDataBuf[ucSize - 1] = ucGetCRC((uint8_t *)&ucAryDataBuf[5], 18); // 0x0A + 8
			break;
		
		case eHART_CMD3:
			ucSize = 40; // 5 + 8 + 26 + 1
		
			ucAryDataBuf[5] = HART_ADDR_SLAVE_HOST_LONG;
			ucAryDataBuf[6] = (stHartLongAddrFrame.ucbitMasterAddr << 7) + (stHartLongAddrFrame.ucbitBurstMode << 6) + stHartLongAddrFrame.ucbitManufacturerID;
			ucAryDataBuf[7] = 0x82;
			ucAryDataBuf[8] = 0x74;
			ucAryDataBuf[9] = 0x2E;
			ucAryDataBuf[10] = 0x96;
			ucAryDataBuf[11] = stHartLongAddrFrame.ucCom;
			ucAryDataBuf[12] = 26;
			ucAryDataBuf[13] = 0x00;
			ucAryDataBuf[14] = eCMD3_SUCCESS;
			vExeCommands(eHART_CMD3, 0, ucAryDataBuf + 15);
		
			ucAryDataBuf[ucSize - 1] = ucGetCRC((uint8_t *)&ucAryDataBuf[5], 34); // 26 + 8
			break;
		
		case eHART_CMD6:
			ucSize = 17; // 5 + 8 + 0x03 + 1
		
			vExeCommands(eHART_CMD6, 0, stHartLongAddrFrame.pucData);
		
			ucAryDataBuf[5] = HART_ADDR_SLAVE_HOST_LONG;
			ucAryDataBuf[6] = (stHartLongAddrFrame.ucbitMasterAddr << 7) + (stHartLongAddrFrame.ucbitBurstMode << 6) + stHartLongAddrFrame.ucbitManufacturerID;
			ucAryDataBuf[7] = 0x82;
			ucAryDataBuf[8] = 0x74;
			ucAryDataBuf[9] = 0x2E;
			ucAryDataBuf[10] = 0x96;
			ucAryDataBuf[11] = stHartLongAddrFrame.ucCom;
			ucAryDataBuf[12] = 0x03;
			ucAryDataBuf[13] = eCMD6_SUCCESS;
			ucAryDataBuf[14] = stLoopConfig.ucPollingAddr;
			ucAryDataBuf[15] = stLoopConfig.eLoopCurMode;
			ucAryDataBuf[ucSize - 1] = ucGetCRC((uint8_t *)&ucAryDataBuf[5], 11); // 0x03 + 8
			break;
		
		case eHART_CMD7:
			ucSize = 18; // 5 + 8 + 0x04 + 1
		
			ucAryDataBuf[5] = HART_ADDR_SLAVE_HOST_LONG;
			ucAryDataBuf[6] = (stHartLongAddrFrame.ucbitMasterAddr << 7) + (stHartLongAddrFrame.ucbitBurstMode << 6) + stHartLongAddrFrame.ucbitManufacturerID;
			ucAryDataBuf[7] = 0x82;
			ucAryDataBuf[8] = 0x74;
			ucAryDataBuf[9] = 0x2E;
			ucAryDataBuf[10] = 0x96;
			ucAryDataBuf[11] = stHartLongAddrFrame.ucCom;
			ucAryDataBuf[12] = 0x04;
			ucAryDataBuf[13] = 0x00;
			ucAryDataBuf[14] = eCMD7_SUCCESS;
			vExeCommands(eHART_CMD7, 0, ucAryDataBuf + 15);
		
			ucAryDataBuf[ucSize - 1] = ucGetCRC((uint8_t *)&ucAryDataBuf[5], 12); // 0x04 + 8
			break;
		
		case eHART_CMD8:
			ucSize = 20; // 5 + 8 + 6 + 1
		
			ucAryDataBuf[5] = HART_ADDR_SLAVE_HOST_LONG;
			ucAryDataBuf[6] = (stHartLongAddrFrame.ucbitMasterAddr << 7) + (stHartLongAddrFrame.ucbitBurstMode << 6) + stHartLongAddrFrame.ucbitManufacturerID;
			ucAryDataBuf[7] = 0x82;
			ucAryDataBuf[8] = 0x74;
			ucAryDataBuf[9] = 0x2E;
			ucAryDataBuf[10] = 0x96;
			ucAryDataBuf[11] = stHartLongAddrFrame.ucCom;
			ucAryDataBuf[12] = 0x06;
			ucAryDataBuf[13] = 0x00;
			ucAryDataBuf[14] = eCMD8Success;
			vExeCommands(eHART_CMD8, 0, ucAryDataBuf + 15);
		
			ucAryDataBuf[ucSize - 1] = ucGetCRC((uint8_t *)&ucAryDataBuf[5], 14); // 0x06 + 8
			break;
		
		case eHART_CMD12:
			ucSize = 40; // 5 + 8 + 0x1A + 1
		
			ucAryDataBuf[5] = HART_ADDR_SLAVE_HOST_LONG;
			ucAryDataBuf[6] = (stHartLongAddrFrame.ucbitMasterAddr << 7) + (stHartLongAddrFrame.ucbitBurstMode << 6) + stHartLongAddrFrame.ucbitManufacturerID;
			ucAryDataBuf[7] = 0x82;
			ucAryDataBuf[8] = 0x74;
			ucAryDataBuf[9] = 0x2E;
			ucAryDataBuf[10] = 0x96;
			ucAryDataBuf[11] = stHartLongAddrFrame.ucCom;
			ucAryDataBuf[12] = 0x1A;
			ucAryDataBuf[13] = 0x00;
			ucAryDataBuf[14] = eCMD12_SUCCESS;
			
			vExeCommands(eHART_CMD12, 0, ucAryDataBuf + 15);
			
			ucAryDataBuf[ucSize - 1] = ucGetCRC((uint8_t *)&ucAryDataBuf[5], 34); // 0x1A + 8
			break;
		case eHART_CMD14:
			ucSize = 32; // 5 + 8 + 0x12 + 1
		
			ucAryDataBuf[5] = HART_ADDR_SLAVE_HOST_LONG;
			ucAryDataBuf[6] = (stHartLongAddrFrame.ucbitMasterAddr << 7) + (stHartLongAddrFrame.ucbitBurstMode << 6) + stHartLongAddrFrame.ucbitManufacturerID;
			ucAryDataBuf[7] = 0x82;
			ucAryDataBuf[8] = 0x74;
			ucAryDataBuf[9] = 0x2E;
			ucAryDataBuf[10] = 0x96;
			ucAryDataBuf[11] = stHartLongAddrFrame.ucCom;
			ucAryDataBuf[12] = 0x12;
			ucAryDataBuf[13] = 0x00;
			ucAryDataBuf[14] = eCMD14_SUCCESS;
		
			vExeCommands(eHART_CMD14, 0, ucAryDataBuf + 15);
			
			ucAryDataBuf[ucSize - 1] = ucGetCRC((uint8_t *)&ucAryDataBuf[5], 26); // 0x12 + 8
			break;
		
		case eHART_CMD15:
			ucSize = 34; // 5 + 8 + 0x14 + 1
			
			ucAryDataBuf[5] = HART_ADDR_SLAVE_HOST_LONG;
			ucAryDataBuf[6] = (stHartLongAddrFrame.ucbitMasterAddr << 7) + (stHartLongAddrFrame.ucbitBurstMode << 6) + stHartLongAddrFrame.ucbitManufacturerID;
			ucAryDataBuf[7] = 0x82;
			ucAryDataBuf[8] = 0x74;
			ucAryDataBuf[9] = 0x2E;
			ucAryDataBuf[10] = 0x96;
			ucAryDataBuf[11] = stHartLongAddrFrame.ucCom;
			ucAryDataBuf[12] = 0x14;
			ucAryDataBuf[13] = 0x00;
			ucAryDataBuf[14] = eCMD15_SUCCESS;
		
			vExeCommands(eHART_CMD15, 0, ucAryDataBuf + 15);
		
			ucAryDataBuf[ucSize - 1] = ucGetCRC((uint8_t *)&ucAryDataBuf[5], 28); // 0x14 + 8
			break;
		
		case eHART_CMD34:
			break;
		
		default:
			break;
	}
	
	if(ucSize != 0)
	{
		while(GET_HART_CARRIER_DET());
		
		HART_RTS_L();
		vHartTxData(ucAryDataBuf, ucSize + 1); // send one more byte
		HART_RTS_H();
	}
}

EnumHartCmdId GetCmdID(uint8_t ucCom)
{
	switch(ucCom)
	{
		case 0:	return eHART_CMD0;
		case 1:	return eHART_CMD1;
		case 2:	return eHART_CMD2;
		case 3:	return eHART_CMD3;
		case 4:	return eHART_CMD4;
		case 5:	return eHART_CMD5;
		case 6:	return eHART_CMD6;
		case 7:	return eHART_CMD7;
		case 8:	return eHART_CMD8;
		case 9:	return eHART_CMD9;
		case 11: return eHART_CMD11;
		case 12: return eHART_CMD12;
		case 13: return eHART_CMD13;
		case 14: return eHART_CMD14;
		case 15: return eHART_CMD15;
		case 16: return eHART_CMD16;
		case 17: return eHART_CMD17;
		case 18: return eHART_CMD18;
		case 19: return eHART_CMD19;
		case 20: return eHART_CMD20;
		case 21: return eHART_CMD21;
		case 22: return eHART_CMD22;
		default: return eHART_CMD5;
	}
}

void vUpdateRxFrameBuffer(uint8_t ucStart)
{
	switch(ucStart)
	{
		case HART_ADDR_HOST_SLAVE_SHORT:
			// PREAMBLE
			stHartShortAddrFrame.ucAryPreamble[0] = 0xff;
			stHartShortAddrFrame.ucAryPreamble[1] = 0xff;
			stHartShortAddrFrame.ucAryPreamble[2] = 0xff;
			stHartShortAddrFrame.ucAryPreamble[3] = 0xff;
			stHartShortAddrFrame.ucAryPreamble[4] = 0xff;
			// START
			stHartShortAddrFrame.ucStart = stHartRxData.ucAryBuffer[gucFrameStartPos];
			// ADDR
			stHartShortAddrFrame.ucbitMasterAddr = (stHartRxData.ucAryBuffer[gucFrameStartPos + 1] & 0x80) ? 1 : 0;
			stHartShortAddrFrame.ucbitBurstMode = (stHartRxData.ucAryBuffer[gucFrameStartPos + 1] & 0x40) ? 1 : 0;
			stHartShortAddrFrame.ucbitPollingAddr = stHartRxData.ucAryBuffer[gucFrameStartPos + 1] & 0x0f;
			// COM
			stHartShortAddrFrame.ucCom = stHartRxData.ucAryBuffer[gucFrameStartPos + 2];
			// BCNT
			stHartShortAddrFrame.ucSize = stHartRxData.ucAryBuffer[gucFrameStartPos + 3];
			// DATA
			// PARITY
			stHartShortAddrFrame.ucParity = stHartRxData.ucAryBuffer[gucFrameStartPos + 4];
			break;
		
		case HART_ADDR_HOST_SLAVE_LONG:
			// PREAMBLE
			stHartLongAddrFrame.ucAryPreamble[0] = 0xff;
			stHartLongAddrFrame.ucAryPreamble[1] = 0xff;
			stHartLongAddrFrame.ucAryPreamble[2] = 0xff;
			stHartLongAddrFrame.ucAryPreamble[3] = 0xff;
			stHartLongAddrFrame.ucAryPreamble[4] = 0xff;
			// START
			stHartLongAddrFrame.ucStart = stHartRxData.ucAryBuffer[gucFrameStartPos];
			// ADDR
			stHartLongAddrFrame.ucbitMasterAddr = (stHartRxData.ucAryBuffer[gucFrameStartPos + 1] & 0x80) ? 1 : 0;
			stHartLongAddrFrame.ucbitBurstMode = (stHartRxData.ucAryBuffer[gucFrameStartPos + 1] & 0x40) ? 1 : 0;
			stHartLongAddrFrame.ucbitManufacturerID = stHartRxData.ucAryBuffer[gucFrameStartPos + 1] & 0x3f;
			// Device Type
			stHartLongAddrFrame.ucDeviceType = stHartRxData.ucAryBuffer[gucFrameStartPos + 2];
			// Device Serial
			stHartLongAddrFrame.ulDeviceId = (((uint32_t)(stHartRxData.ucAryBuffer[gucFrameStartPos + 3])) << 16) + 
												(((uint32_t)(stHartRxData.ucAryBuffer[gucFrameStartPos + 4])) << 8) + 
															stHartRxData.ucAryBuffer[gucFrameStartPos + 5];
			// COM
			stHartLongAddrFrame.ucCom = stHartRxData.ucAryBuffer[gucFrameStartPos + 6];
			// BCNT
			stHartLongAddrFrame.ucSize = stHartRxData.ucAryBuffer[gucFrameStartPos + 7];
			// DATA
			// Parity
			if(stHartLongAddrFrame.ucSize != 0)
			{
				stHartLongAddrFrame.pucData = (uint8_t *)&stHartRxData.ucAryBuffer[gucFrameStartPos + 8];
				stHartLongAddrFrame.ucParity = stHartRxData.ucAryBuffer[gucFrameStartPos + 8 + stHartLongAddrFrame.ucSize + 1];
			}
			else
			{
				stHartLongAddrFrame.pucData = NULL;
				stHartLongAddrFrame.ucParity = stHartRxData.ucAryBuffer[gucFrameStartPos + 8];
			}
			break;
		
		default:
			break;
	}
}

void vHartRxBufferClr(void)
{
	memset((uint8_t *)stHartRxData.ucAryBuffer, 0x00, HART_RX_BUFFER_SIZE);
	stHartRxData.uiDataCnt = 0;
}

void vHartTxData(uint8_t *pdata, uint8_t ucSize)
{
	uint8_t i = 0;
	
	for(i = 0; i < ucSize; i++)
	{
		FL_UART_WriteTXBuff(UART0, (uint8_t)pdata[i]);
		while(FL_UART_IsActiveFlag_TXBuffEmpty(UART0) != FL_SET);
    }
}
